package com.nbufe.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nbufe.domain.ResponseResult;
import com.nbufe.domain.entity.*;
import com.nbufe.domain.entity.Process;
import com.nbufe.domain.vo.*;
import com.nbufe.domain.vo.electricheat.CalcElectricHeatCarbonVo;
import com.nbufe.mapper.*;
import com.nbufe.service.*;
import com.nbufe.utils.BeanCopyUtils;
import com.nbufe.utils.HttpContextUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @author LZH
 * @date 2023/4/2
 */
@Service
public class FileServieImpl implements FileServie {

    @Resource
    private FossilFuelMapper fossilFuelMapper;

    @Resource
    private MaterialMapper materialMapper;

    @Resource
    private ElectricHeatMapper electricHeatMapper;

    @Resource
    private ProcessMapper processMapper;

    @Resource
    private ElectricHeatService electricHeatService;

    @Resource
    private FossilFuelService fossilFuelService;

    @Resource
    private IndustoryProduceService industoryProduceService;

    @Resource
    private FixCarbonService fixCarbonService;

    @Resource
    private EmissionOriginMapper emissionOriginMapper;

    private List<FossilFuel> fossilFuelList = new ArrayList<>();

    private List<ElectricHeat> electricHeatList = new ArrayList<>();

    private List<IndustoryProduce> industoryProduceList = new ArrayList<>();

    private List<FixCarbon> fixCarbonList = new ArrayList<>();

    @Override
    public void exportExcel(String fileName, HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);
            List<FossilFuel> fossilFuelList = fossilFuelMapper.selectList(null);

            List<ExportFossiFuelVo> exportFossiFuelVos = BeanCopyUtils.copyBeanList(fossilFuelList, ExportFossiFuelVo.class);
            for (ExportFossiFuelVo vo : exportFossiFuelVos) {
                for (EmissionOrigin emissionOrigin : emissionOriginList) {
                    if (emissionOrigin.getId().equals(vo.getFossiId())) {
                        vo.setName(emissionOrigin.getName());
                        break;
                    }
                }
            }
            EasyExcel.write(response.getOutputStream(), ExportFossiFuelVo.class)
                    .sheet(fileName).doWrite(exportFossiFuelVos);
        } catch (IOException e) {
        }
    }

    @Override
    public void exportElectricHeatExcel(String fileName, HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);

            List<ElectricHeat> electricHeatList = electricHeatMapper.selectList(null);
            List<ExportElectricHeatVo> exportElectricHeatVos = BeanCopyUtils.copyBeanList(electricHeatList, ExportElectricHeatVo.class);
            for (ExportElectricHeatVo vo : exportElectricHeatVos) {
                for (EmissionOrigin emissionOrigin : emissionOriginList) {
                    if (emissionOrigin.getId().equals(vo.getMaterialId())) {
                        vo.setName(emissionOrigin.getName());
                        break;
                    }
                }
            }
            EasyExcel.write(response.getOutputStream(), ExportElectricHeatVo.class)
                    .sheet(fileName).doWrite(exportElectricHeatVos);
        } catch (IOException e) {
        }
    }

    @Override
    public void exportIndustoryProduceExcel(String fileName, HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);

            List<IndustoryProduce> industoryProduceList = industoryProduceService.list();
            List<Process> processList = processMapper.selectList(null);
            List<ExportIndustoryProduceVo> exportIndustoryProduceVos = BeanCopyUtils.copyBeanList(industoryProduceList, ExportIndustoryProduceVo.class);
            for (ExportIndustoryProduceVo vo : exportIndustoryProduceVos) {
                for (EmissionOrigin emissionOrigin : emissionOriginList) {
                    if (emissionOrigin.getId().equals(vo.getMaterialId())) {
                        vo.setName(emissionOrigin.getName());
                        break;
                    }
                }
                for (Process process : processList) {
                    if (process.getId().equals(vo.getProcessId())) {
                        vo.setProcess(process.getName());
                    }
                }
            }
            EasyExcel.write(response.getOutputStream(), ExportIndustoryProduceVo.class)
                    .sheet(fileName).doWrite(exportIndustoryProduceVos);
        } catch (IOException e) {
        }
    }

    @Override
    public ResponseResult importIndustoryProduceExcel(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            EasyExcel.read(inputStream, ImportIndustoryProduceVo.class, new AnalysisEventListener<ImportIndustoryProduceVo>() {
                        @Override
                        public void invoke(ImportIndustoryProduceVo vo, AnalysisContext analysisContext) {

                            List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);
                            List<Process> processList = processMapper.selectList(null);
                            for (EmissionOrigin emissionOrigin : emissionOriginList) {
                                if (emissionOrigin.getName().equals(vo.getName())) {
                                    vo.setMaterialId(emissionOrigin.getId());
                                    break;
                                }
                            }
                            for (Process process : processList) {
                                if (process.getName().equals(vo.getProcess())) {
                                    vo.setProcessId(process.getId());
                                    break;
                                }
                            }
                            IndustoryProduce industoryProduce = BeanCopyUtils.copyBean(vo, IndustoryProduce.class);
                            if (industoryProduce.getMaterialId() != null) {
                                industoryProduceList.add(industoryProduce);
                            }
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                            for (IndustoryProduce industoryProduce : industoryProduceList) {
                                industoryProduce.setCarbonEmission(
                                        BigDecimal.valueOf(industoryProduce.getConsumption())
                                                .multiply(BigDecimal.valueOf(industoryProduce.getEmissionFactor()))
                                                .setScale(2, RoundingMode.UP)
                                                .doubleValue()
                                );
                            }
                            industoryProduceService.saveBatch(industoryProduceList);
                            industoryProduceList.clear();
                        }
                    })
                    .sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult importFixCarbonExcel(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            EasyExcel.read(inputStream, ImportFixCarbonVo.class, new AnalysisEventListener<ImportFixCarbonVo>() {
                        @Override
                        public void invoke(ImportFixCarbonVo vo, AnalysisContext analysisContext) {

                            LambdaQueryWrapper<Material> queryWrapper = new LambdaQueryWrapper<>();
                            queryWrapper.eq(Material::getProduceStage, 4);
                            List<Material> materialList = materialMapper.selectList(queryWrapper);
                            for (Material material : materialList) {
                                if (material.getName().equals(vo.getName())) {
                                    vo.setFixCarbonId(material.getId());
                                    break;
                                }
                            }
                            FixCarbon fixCarbon = BeanCopyUtils.copyBean(vo, FixCarbon.class);
                            fixCarbonList.add(fixCarbon);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                            for (FixCarbon fixCarbon : fixCarbonList) {
                                fixCarbon.setCarbonEmission(
                                        BigDecimal.valueOf(fixCarbon.getProduction())
                                                .multiply(BigDecimal.valueOf(fixCarbon.getEmissionFactor()))
                                                .setScale(2, RoundingMode.UP)
                                                .doubleValue()
                                );
                            }
                            fixCarbonService.saveBatch(fixCarbonList);
                            fixCarbonList.clear();
                        }
                    })
                    .sheet("fixcarbon").doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseResult.okResult();
    }

    @Override
    public void exportFixCarbonExcel(String fileName, HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            List<EmissionOrigin> emissionOriginList = emissionOriginMapper.selectList(null);

            List<FixCarbon> fixCarbonList = fixCarbonService.list();
            List<ExportFixCarbonVo> exportFixCarbonVos = BeanCopyUtils.copyBeanList(fixCarbonList, ExportFixCarbonVo.class);
            for (ExportFixCarbonVo vo : exportFixCarbonVos) {
                for (EmissionOrigin emissionOrigin : emissionOriginList) {
                    if (emissionOrigin.getId().equals(vo.getFixCarbonId())) {
                        vo.setName(emissionOrigin.getName());
                        break;
                    }
                }
            }
            EasyExcel.write(response.getOutputStream(), ExportFixCarbonVo.class)
                    .sheet(fileName).doWrite(exportFixCarbonVos);
        } catch (IOException e) {
        }
    }

    @Override
    public ResponseResult importExcel(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            EasyExcel.read(inputStream, ImportFossiFuelVo.class, new AnalysisEventListener<ImportFossiFuelVo>() {
                        @Override
                        public void invoke(ImportFossiFuelVo importFossiFuelVo, AnalysisContext analysisContext) {
                            List<Material> materialList = getAllMaterials();
                            for (Material material : materialList) {
                                if (material.getName().equals(importFossiFuelVo.getName())) {
                                    importFossiFuelVo.setFossiId(material.getId());
                                    break;
                                }
                            }
                            FossilFuel fossilFuel = BeanCopyUtils.copyBean(importFossiFuelVo, FossilFuel.class);
                            fossilFuelList.add(fossilFuel);
                            System.out.println(fossilFuel);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                            fossilFuelService.saveBatch(fossilFuelList);
                            for (FossilFuel fossilFuel : fossilFuelList) {
                                ActivityLevelVo activityLevelVo = BeanCopyUtils.copyBean(fossilFuel, ActivityLevelVo.class);
                                fossilFuelService.calcActivityLevelByMonth(activityLevelVo);

                                CalcEmissionFactorVo calcEmissionFactorVo = BeanCopyUtils.copyBean(fossilFuel, CalcEmissionFactorVo.class);
                                fossilFuelService.calcEmissionFactoryByMonth(calcEmissionFactorVo);

                                CalCO2EmissionVO calCO2EmissionVO = BeanCopyUtils.copyBean(fossilFuel, CalCO2EmissionVO.class);
                                fossilFuelService.calcCo2EmissionByMonth(calCO2EmissionVO);
                            }

                            fossilFuelList.clear();
                        }
                    })
                    .sheet("fossilfuel").doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseResult.okResult();
    }

    private List<Material> getAllMaterials() {
        return materialMapper.selectList(null);
    }

    @Override
    public ResponseResult importElectricHeatExcel(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            EasyExcel.read(inputStream, ImportElectricHeatVo.class, new AnalysisEventListener<ImportElectricHeatVo>() {
                        @Override
                        public void invoke(ImportElectricHeatVo vo, AnalysisContext analysisContext) {
                            List<Material> materialList = getAllMaterials();
                            for (Material material : materialList) {
                                if (material.getName().equals(vo.getName())) {
                                    vo.setMaterialId(material.getId());
                                    break;
                                }
                            }
                            ElectricHeat electricHeat = BeanCopyUtils.copyBean(vo, ElectricHeat.class);
                            electricHeatList.add(electricHeat);
                            System.out.println(electricHeat);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                            electricHeatService.saveBatch(electricHeatList);

                            for (ElectricHeat electricHeat : electricHeatList) {
                                electricHeatService.calcYearMonthElectricHeat(BeanCopyUtils.copyBean(electricHeat, CalcElectricHeatCarbonVo.class));
                            }

                            electricHeatList.clear();
                        }
                    })
                    .sheet("electricheat").doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseResult.okResult();
    }

}
